package audio;



import java.io.IOException;
import java.util.Vector;
import javax.media.CaptureDeviceInfo;
import javax.media.CaptureDeviceManager;
import javax.media.DataSink;
import javax.media.Format;
import javax.media.MediaLocator;
import javax.media.NoDataSinkException;
import javax.media.NoDataSourceException;
import javax.media.NoPlayerException;
import javax.media.NoProcessorException;
import javax.media.Processor;
import javax.media.control.StreamWriterControl;
import javax.media.control.TrackControl;
import javax.media.format.AudioFormat;
import javax.media.protocol.ContentDescriptor;
import javax.media.protocol.DataSource;
import javax.media.protocol.FileTypeDescriptor;
import javax.media.Manager;

import jmapps.util.StateHelper;



public class Captura {
	
	//private CaptureDeviceManager sysMan;
	private CaptureDeviceInfo mic;
	private DataSource som ;
	private Processor captador;
	//private Player captador;	
	
	public Captura() throws MicrofoneAusenteException, NoDataSourceException, IOException, NoPlayerException{		
			this.mic = this.carregaMic();
			this.dadosMic();			
			this.captador = Manager.createProcessor(som);			
			//this.captador = Manager.createPlayer(som);	
	}
	
	public CaptureDeviceInfo getMic() {
		return mic;
	}

	public void setMic(CaptureDeviceInfo mic) {
		this.mic = mic;
	}

	public DataSource getSom() {
		return som;
	}

	public void setSom(DataSource som) {
		this.som = som;
	}

	public Processor getCaptador() {
		return captador;
	}

	public void setCaptador(Processor captador) {
		this.captador = captador;
	}

	public CaptureDeviceInfo carregaMic() throws MicrofoneAusenteException{		
		CaptureDeviceInfo microfone = null;
		AudioFormat f = new AudioFormat(AudioFormat.LINEAR, 44100, 16, 2);		
		Vector<CaptureDeviceInfo> v = CaptureDeviceManager.getDeviceList(f);
		if (v.size() > 0){
		 	 microfone = v.firstElement();
		} else{
			throw new MicrofoneAusenteException();
		}	
		return microfone;	
	}
	
	public MediaLocator localizaMic(){
		return this.mic.getLocator();
	}
	
	public void dadosMic() throws NoDataSourceException, IOException{
		this.som = Manager.createDataSource(this.localizaMic());
	}
	
	public void capturar() throws NoProcessorException, IOException{		
		this.captador.start();		
	}
	
	public DataSource configuraRTP(){
		StateHelper sh = new StateHelper(this.captador);		
		//configura o processor
		if(!sh.configure(100000)){
			System.out.println("estourou o tempo.");
		}
		
		//selecionando o conteudo a ser transmitido
		ContentDescriptor cd = new ContentDescriptor(ContentDescriptor.RAW_RTP);
		this.captador.setContentDescriptor(cd);		
		
		//Determinando qual o formato que as faixas irao tranportar
		TrackControl [] tracks = this.captador.getTrackControls();        
        AudioFormat chosen = new AudioFormat(AudioFormat.LINEAR, 44100, 16, 2);
        for (int i = 0; i < tracks.length; i++) {            
            tracks[i].setFormat(chosen);        
        }
        
		//configura o processor
		if(!sh.realize(10000)){
			System.out.println("estourou o tempo.");
		}
		return this.captador.getDataOutput();
	}
	
	public void gravaAudio() throws NoDataSinkException, SecurityException, IOException, NoProcessorException{
		StateHelper sh = new StateHelper(this.captador);		
		//configura o processor
		if(!sh.configure(10000)){
			System.out.println("estourou o tempo.");
		}		
		//descreve o tipo de arquivo a ser gravado
		FileTypeDescriptor fd = new FileTypeDescriptor(FileTypeDescriptor.WAVE);
		this.captador.setContentDescriptor(fd);			
		//configura o processor
		if(!sh.realize(10000)){
			System.out.println("estourou o tempo.");
		}
		//prepara��o da captura e grava��o
		DataSource fonteAudio = this.captador.getDataOutput();
		MediaLocator arqDestino = new MediaLocator("file://teste.wav");
		//gera o escritor do arquivo wav e o arquivo
		DataSink escritor = Manager.createDataSink(fonteAudio, arqDestino);		
		escritor.open();
		//limitador da captura
		StreamWriterControl swc = (StreamWriterControl)this.captador.getControl("javax.media.control.StreamWriterControl");
		if(swc != null){
			swc.setStreamSizeLimit(5000000);
		}
		//iniciando a captura e escrita do arquivo
		escritor.start();
		capturar();
		//terminando a captura
		sh.playToEndOfMedia(5000);
		sh.close();		
		escritor.stop();
		escritor.close();
	}
	
	public static void main(String args[])
    {
       Captura c;
       Recepcao r;
		try {
			c = new Captura();
			//c.gravaAudio();			
			c.capturar();			
			r = new Recepcao(c.getCaptador().getDataOutput());
			r.receber();
		} catch (NoProcessorException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (NoDataSourceException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (MicrofoneAusenteException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();			
		} catch (NoPlayerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}/* catch (NoDataSinkException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/ catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}       
    }
}
